package com.apobates.forum.orize.spring.boot;

import com.apobates.forum.orize.OrizeExecutorFactory;
import com.apobates.forum.orize.core.OrizeAuthIgnoreConfig;
import com.apobates.forum.orize.core.OrizeMemberQuery;
import com.apobates.forum.orize.core.OrizeMemberRolePredicate;
import com.apobates.forum.orize.core.plug.OrizeMemberRoleAnyContainsPredicate;
import com.apobates.forum.orize.core.plug.OrizeMemberRoleContainsAllPredicate;
import com.apobates.forum.orize.spring.OrizeAuthHelper;
import com.apobates.forum.orize.spring.OrizeAuthSpringInterceptorImpl;
import com.apobates.forum.orize.spring.mvc.OrizeAuthInterceptorConfig;
import com.apobates.forum.orize.spring.mvc.OrizeServletContextInitializer;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import javax.servlet.ServletContext;

/**
 * Orize的自动装配类
 * @author xiaofanku@live.cn
 * @since 20210821
 */
@Configuration
@ConditionalOnClass(OrizeExecutorFactory.class)
@EnableConfigurationProperties(OrizeProperties.class)
@Import({OrizeAuthInterceptorConfig.class, OrizeServletContextInitializer.class})
public class OrizeSpringAutoConfiguration {
    @Autowired
    private OrizeProperties orizeProperties;
    private final static Logger logger = LoggerFactory.getLogger(OrizeSpringAutoConfiguration.class);

    public OrizeSpringAutoConfiguration(){
        System.out.println("*-------------------------------------------------------------");
        System.out.println("*");
        System.out.println("* Orize URL Authentication");
        System.out.println("*");
        System.out.println("* Copyright (c) 2021 xiaofanku");
        System.out.println("* Mail: xiaofanku@live.cn");
        System.out.println("* Build: OpenJDK 11.x");
        System.out.println("*-------------------------------------------------------------");
    }

    //orize 请求地址验证配置开始
    //用户信息查询
    @Bean(name="memberQuery")
    public OrizeMemberQuery getMemberQuery(){
        String omqImpClass = orizeProperties.getQueryClass();
        try {
            if(null!=omqImpClass) {
                Class<OrizeMemberQuery> mqc = (Class<OrizeMemberQuery>) Class.forName(omqImpClass).asSubclass(OrizeMemberQuery.class);
                return mqc.getDeclaredConstructor().newInstance();
            }
        }catch (Exception e){
            if(logger.isDebugEnabled()){
                logger.debug(e.getMessage(), e);
            }
        }
        return null;
    }

    //不需要验证的配置
    @Bean(name="cusIgnoreConfig")
    public OrizeAuthIgnoreConfig getIgnoreConfig(){
        return optionIgnoreConfig(OrizeAuthIgnoreConfig.defaultInstance(), orizeProperties);
    }

    private OrizeAuthIgnoreConfig optionIgnoreConfig(OrizeAuthIgnoreConfig ignoreConfig, OrizeProperties orizeProperties){
        OrizeAuthIgnoreConfig _tmp = ignoreConfig;
        final String SPLITER=",";
        if(null!=orizeProperties.getIgnoreDomain()){
            _tmp = _tmp.setIgnoreDomain(orizeProperties.getIgnoreDomain().split(SPLITER));
        }
        if(StringUtils.isNotBlank(orizeProperties.getIgnorePath())){
            _tmp = _tmp.setIgnoreRequestPath(orizeProperties.getIgnorePath().split(SPLITER));
        }
        if(StringUtils.isNotBlank(orizeProperties.getIgnoreExt())){
            _tmp = _tmp.setIgnoreMediaType(orizeProperties.getIgnoreExt().split(SPLITER));
        }
        return _tmp;
    }

    //资源验证助手类
    @Bean(name="orizeAuthHelper")
    public OrizeAuthHelper getAuthHelper(@NonNull OrizeMemberQuery memberQuery, @Nullable OrizeAuthIgnoreConfig cusIgnoreConfig, ServletContext sc){
        OrizeAuthHelper.Builder builder = OrizeAuthHelper
                .defaultInstance(orizeProperties.getLoader(), sc)
                .setMemberQuery(memberQuery)
                .setIgnoreConfig(cusIgnoreConfig);
        if(!"anno".equalsIgnoreCase(orizeProperties.getLoader())){
            builder = builder.setNotAnnoResourcePath(orizeProperties.getPath());
        }
        return builder.build();
    }

    //用户角色验证规则
    @Bean(name="memberRolePredicate")
    public OrizeMemberRolePredicate getRolePre(){
        if("any".equalsIgnoreCase(orizeProperties.getRoleMatch())) {
            return new OrizeMemberRoleAnyContainsPredicate();
        }
        return new OrizeMemberRoleContainsAllPredicate();
    }

    //资源地址验证过滤器
    @Bean(name="orizeAuthInterceptor")
    public OrizeAuthSpringInterceptorImpl getOrizeAuthInter(){
        //OrizeAuthHelper orizeAuthHelper, OrizeMemberRolePredicate memberRolePredicate
        return new OrizeAuthSpringInterceptorImpl();
    }
}
